package com.example.ivideo_2211a.fg

import android.view.View
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.common.mvi.BaseFragment
import com.example.ivideo_2211a.R
import com.example.ivideo_2211a.adapter.CategoryAdapter
import com.example.ivideo_2211a.databinding.FragmentHomeBinding
import com.example.ivideo_2211a.home.*
import com.example.ivideo_2211a.model.CategoryModel
import com.alibaba.android.arouter.launcher.ARouter
import com.google.gson.Gson

import android.animation.ValueAnimator
import kotlin.random.Random
import android.content.Intent
import android.graphics.Path
import android.graphics.PathMeasure
import android.os.Handler
import android.os.Looper
import android.widget.ImageView
import android.view.ViewGroup
import androidx.core.animation.doOnEnd
import com.blankj.utilcode.util.SPUtils
import com.example.ivideo_2211a.activity.GoldCoinDetailActivity

/**
 * HomeFragment 是一个用于展示首页视频列表的 Fragment。
 * 它继承自 BaseFragment，并实现了与 ViewModel 和 ViewBinding 的交互逻辑，
 * 包括下拉刷新、上拉加载更多、错误处理等功能。
 */
class HomeFragment : BaseFragment<FragmentHomeBinding, HomeViewModel, HomeIntent, HomeViewState>() {
    // 奖励相关
    private val prefs by lazy { requireContext().getSharedPreferences("gold_coin", 0) }
    private var coinCount: Int
        get() = prefs.getInt("coin_count", 0)
        set(value) { prefs.edit().putInt("coin_count", value).apply() }
    private val rewardInterval = 10_000L // 10秒
    private val maxDailyReward = 2
    private var coinCounts: Int=1
    private var rewardTimes: Int
        get() = prefs.getInt("reward_times", 0)
        set(value) { prefs.edit().putInt("reward_times", value).apply() }
    private var lastRewardDay: Long
        get() = prefs.getLong("last_reward_day", 0L)
        set(value) { prefs.edit().putLong("last_reward_day", value).apply() }
    private var countdownSeconds = (rewardInterval / 1000).toInt()
    private val handler = Handler(Looper.getMainLooper())
    private val countdownRunnable = object : Runnable {
        override fun run() {
            val nowDay = System.currentTimeMillis() / (24 * 60 * 60 * 1000)
            if (lastRewardDay != nowDay) {
                // 新的一天，重置奖励
                rewardTimes = 0
                lastRewardDay = nowDay
            }
            if (rewardTimes >= maxDailyReward) {
                binding.tvGoldCoinCountdown.text = "今日领取完毕"
                // 今日已达上限，不再弹窗
                handler.postDelayed(this, 1000 * 60) // 1分钟检查一次是否到新的一天
                return
            }
            if (countdownSeconds > 0) {
                binding.tvGoldCoinCountdown.text = "下次奖励：${countdownSeconds}s"
                countdownSeconds--
                handler.postDelayed(this, 1000)
            } else {
                // 倒计时结束，发放奖励
                rewardTimes = rewardTimes + 1
                lastRewardDay = nowDay
                val rewardAmount = Random.nextInt(1, 11) // 1~10 随机金币
                playCoinFlyAnimAndShowDialog(rewardAmount)
                if (rewardTimes >= maxDailyReward) {
                    binding.tvGoldCoinCountdown.text = "今日领取完毕"
                    handler.postDelayed(this, 1000 * 60) // 1分钟检查一次是否到新的一天
                } else {
                    countdownSeconds = (rewardInterval / 1000).toInt()
                    binding.tvGoldCoinCountdown.text = "下次奖励：${countdownSeconds}s"
                    handler.postDelayed(this, 1000)
                }
            }
        }
    }

    override fun onStart() {
        super.onStart()
        // 启动时刷新金币数量显示
        binding.goldCoinView.setCoinCount(coinCount)
        binding.tvGoldCoinTotal.text = "当前金币：$coinCount"
        // 检查是否新的一天，重置奖励
        val nowDay = System.currentTimeMillis() / (24 * 60 * 60 * 1000)
        if (lastRewardDay != nowDay) {
            rewardTimes = 0
            lastRewardDay = nowDay
        }
        SPUtils.getInstance().put("coin_count", coinCount)
        handler.post(countdownRunnable)
    }

    override fun onStop() {
        super.onStop()
        handler.removeCallbacks(countdownRunnable)
    }

    // 金币飞行动画：从RecyclerView左上角到金币View
    private fun playCoinFlyAnimAndShowDialog(reward: Int) {
        val startView = binding.recyclerView
        val endView = binding.goldCoinView

        val startLoc = IntArray(2)
        val endLoc = IntArray(2)
        startView.getLocationOnScreen(startLoc)
        endView.getLocationOnScreen(endLoc)

        val animView = ImageView(requireContext()).apply {
            setImageResource(R.drawable.ic_gold_coin)
            layoutParams = ViewGroup.LayoutParams(80, 80)
            x = startLoc[0].toFloat()
            y = startLoc[1].toFloat()
        }
        (requireActivity().window.decorView as ViewGroup).addView(animView)

        val path = Path().apply {
            moveTo(startLoc[0].toFloat(), startLoc[1].toFloat())
            quadTo(
                (startLoc[0] + endLoc[0]) / 2f, startLoc[1] - 300f,
                endLoc[0].toFloat(), endLoc[1].toFloat()
            )
        }

        val pathMeasure = PathMeasure(path, false)
        val anim = ValueAnimator.ofFloat(0f, pathMeasure.length)
        val pos = FloatArray(2)
        anim.duration = 800
        anim.addUpdateListener {
            val value = it.animatedValue as Float
            pathMeasure.getPosTan(value, pos, null)
            animView.x = pos[0]
            animView.y = pos[1]
            // 可加旋转、缩放等效果
            animView.rotation = 360 * (value / pathMeasure.length)
            animView.alpha = 1f - 0.3f * (value / pathMeasure.length)
        }
        anim.doOnEnd {
            (requireActivity().window.decorView as ViewGroup).removeView(animView)
            // 动画结束后弹窗
            showGoldCoinRewardDialog(reward)
        }
        anim.start()
    }

    private fun showGoldCoinRewardDialog(amount: Int) {
        val dialog = com.example.ivideo_2211a.widget.GoldCoinRewardDialog(requireContext(), amount) {
            // 点击“开心收下”时加上奖励
            coinCount = coinCount + amount
            binding.goldCoinView.setCoinCount(coinCount)
            binding.tvGoldCoinTotal.text = "当前金币：$coinCount"
        }
        dialog.show()
    }

    // 旧奖励逻辑已被倒计时逻辑替换，无需rewardRunnable和updateGoldCoinInfo

    /**
     * 懒加载获取 HomeViewModel 实例。
     */
    override val viewModel: HomeViewModel by viewModels()

    /**
     * 视频列表适配器，用于在 RecyclerView 中展示视频数据。
     */
    private lateinit var videoAdapter: VideoAdapter
    
    /**
     * 分类标签适配器，用于在 RecyclerView 中展示分类标签。
     */
    private lateinit var categoryAdapter: CategoryAdapter
    
    /**
     * 分类数据列表
     */
    private val categories = listOf(
        CategoryModel("1", "关注", false),
        CategoryModel("2", "推荐", true),
        CategoryModel("3", "Vlog", false),
        CategoryModel("4", "影视", false),
        CategoryModel("5", "娱乐", false),
        CategoryModel("6", "体育", false),
        CategoryModel("7", "NBA", false),
        CategoryModel("8", "农人", false)
    )
    
    /**
     * 当前选中的分类
     */
    private var selectedCategoryId = "1"

    /**
     * 获取当前 Fragment 对应的布局资源 ID。
     *
     * @return 布局资源 ID，类型为 Int。
     */
    override fun getLayoutId(): Int = R.layout.fragment_home

    /**
     * 初始化视图组件，包括 RecyclerView、SwipeRefreshLayout 和错误提示视图。
     * 并发送初始加载数据的意图。
     */

    override fun setupViews() {
        setupCategoryRecyclerView()
        setupRecyclerView()
        setupSwipeRefresh()
        setupErrorView()

        // 金币View点击跳转
        binding.goldCoinView.setOnClickListener {
            // 跳转到金币明细页（请替换为实际Activity）
            startActivity(Intent(requireContext(), GoldCoinDetailActivity::class.java))
        }
        binding.searchIcon.setOnClickListener {
            navigateToSearch()
        }
        binding.searchText.setOnClickListener {
            navigateToSearch()
        }

        // 初始加载数据
        sendIntent(HomeIntent.LoadVideos)
        // updateGoldCoinInfo() 已彻底移除，无需调用
    }

    private fun navigateToSearch() {
        ARouter.getInstance().build("/app/SearchActivity").navigation()
    }

    /**
     * 配置分类标签 RecyclerView
     */
    private fun setupCategoryRecyclerView() {
        categoryAdapter = CategoryAdapter { category ->
            onCategorySelected(category)
        }
        
        binding.categoryRecyclerView.apply {
            adapter = categoryAdapter
            layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        }
        
        // 设置初始数据
        categoryAdapter.submitList(categories)
    }
    
    /**
     * 处理分类选择
     */
    private fun onCategorySelected(selectedCategory: CategoryModel) {
        if (selectedCategory.id == selectedCategoryId) return
        
        selectedCategoryId = selectedCategory.id
        
        // 更新分类列表状态
        val updatedCategories = categories.map { category ->
            category.copy(isSelected = category.id == selectedCategory.id)
        }
        categoryAdapter.submitList(updatedCategories)
        
        // 根据选中的分类加载对应的视频数据
        // 这里可以发送不同的Intent或者在Intent中传递分类参数
        sendIntent(HomeIntent.LoadVideos)
    }

    /**
     * 配置 RecyclerView，设置适配器和布局管理器，并添加滚动监听以实现上拉加载更多功能。
     */
    private fun setupRecyclerView() {
        coinCounts++
        SPUtils.getInstance().put("coinCount", coinCounts)
        videoAdapter = VideoAdapter { video ->
            val gson = Gson()
            val videoDataJson = gson.toJson(video)

            // 使用ARouter跳转，传递JSON字符串
            ARouter.getInstance()
                .build("/playvideo/PlayVideoActivity")  // 修正：添加模块前缀
                .withString("videoDataJson", videoDataJson)
                .navigation()

        }

        binding.recyclerView.apply {
            adapter = videoAdapter
            layoutManager = LinearLayoutManager(requireContext())

            // 添加滚动监听，实现上拉加载更多
            addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)

                    val layoutManager = recyclerView.layoutManager as LinearLayoutManager
                    val visibleItemCount = layoutManager.childCount
                    val totalItemCount = layoutManager.itemCount
                    val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()

                    val currentState = viewModel.viewState.value
                    if (!currentState.isLoadingMore && currentState.hasMore &&
                        (visibleItemCount + firstVisibleItemPosition) >= totalItemCount - 3) {
                        sendIntent(HomeIntent.LoadMoreVideos(currentState.currentPage + 1))
                    }
                }
            })
        }
    }

    /**
     * 设置下拉刷新监听器，当用户下拉刷新时触发刷新视频列表的操作。
     */
    private fun setupSwipeRefresh() {
        binding.swipeRefreshLayout.setOnRefreshListener {
            sendIntent(HomeIntent.RefreshVideos)
        }
    }

    /**
     * 设置错误提示视图点击事件，点击后重新加载数据。
     */
    private fun setupErrorView() {
        binding.errorTextView.setOnClickListener {
            sendIntent(HomeIntent.LoadVideos)
        }
    }

    /**
     * 根据 ViewState 更新界面状态，包括加载状态、错误状态和视频列表内容。
     *
     * @param state 当前的 HomeViewState 状态对象，包含所有需要更新的 UI 数据。
     */
    override fun renderViewState(state: HomeViewState) {
        // 更新加载状态
        binding.progressBar.visibility = if (state.isLoading) View.VISIBLE else View.GONE
        binding.swipeRefreshLayout.isRefreshing = state.isRefreshing

        // 更新错误状态
        binding.errorTextView.visibility = if (state.error != null && state.videos.isEmpty()) {
            View.VISIBLE
        } else {
            View.GONE
        }

        // 更新视频列表
        videoAdapter.submitList(state.videos)

        // 隐藏/显示RecyclerView
        binding.recyclerView.visibility = if (state.videos.isNotEmpty()) {
            View.VISIBLE
        } else {
            View.GONE
        }
    }
}
